using System;
using System.Collections.Generic;

namespace AIFSContentManagementSystem.Criteria
{
    using Exceptions;

    public class DefaultExpressionFactory : IExpressionFactory
    {
        public Expression CreateInstance(ExpressionDataType DataType)
        {
            if (DataType == ExpressionDataType.UNSET)
                throw new ArgumentNullException("DataType is required to create the Expression");

            Expression expression = null;
            switch (DataType)
            {
                case ExpressionDataType.STRING:
                    expression = new StringExpression();
                    break;
                case ExpressionDataType.NUMERIC:
                    expression = new NumericExpression();
                    break;
                case ExpressionDataType.DATE:
                    expression = new DateExpression();
                    break;
                case ExpressionDataType.BOOLEAN:
                    expression = new BooleanExpression();
                    break;
            }

            if (expression == null)
                throw new NotSupportedException(string.Format("Expression of type {0} is not supported", DataType));

            return expression;
        }

        public Expression CreateInstance(string DataType)
        {
            ExpressionDataType dataType = ExpressionDataType.UNSET;
            try
            {
                dataType = (ExpressionDataType)Enum.Parse(typeof(ExpressionDataType), DataType);
            }
            catch
            {
                dataType = ExpressionDataType.UNSET;
            }

            return CreateInstance(dataType);
        }

        public List<Expression> CreateFromArray(string[] StringExpression)
        {
            try
            {
                List<Expression> expressionList = new List<Expression>();
                for (int i = 0; i < StringExpression.Length; )
                {
                    string leftOperand = StringExpression[i++];
                    string dataType = StringExpression[i++];
                    string oper = StringExpression[i++];
                    string rightOperand = StringExpression[i++];

                    if (string.IsNullOrEmpty(rightOperand) || string.IsNullOrEmpty(dataType) || string.IsNullOrEmpty(oper) || string.IsNullOrEmpty(leftOperand))
                        throw new AIFSContentManagementSystemException("Xml does not contain either the right operand, the operator, the left operand or the data type");

                    Expression expression = Expression.CreateInstance(dataType);
                    expression.ExpressionElement.LeftOperand = leftOperand;
                    expression.ExpressionElement.Oper = oper;
                    expression.ExpressionElement.RightOperand = rightOperand;

                    expressionList.Add(expression);
                }

                return expressionList;
            }
            catch (AIFSContentManagementSystem.Exceptions.AIFSContentManagementSystemException aex)
            {
                throw aex;
            }
            catch (Exception ex)
            {
                throw new AIFSContentManagementSystem.Exceptions.AIFSContentManagementSystemException("Could not serealize to object", ex);
            }
        }
    }
}
